package com.casa.POI.dianping;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Property;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;



public class FetchShopUrlsExecutor extends CityThreadsExecutor {
	
	public FetchShopUrlsExecutor(int cityId) {
		super(cityId);
	}

	public List<ShopUrl> fetchShopUrls(String pageUrlStr) throws IOException, XPatherException {
		List<ShopUrl> shopUrls = new ArrayList<ShopUrl>();
		TagNode node = SpiderUtil.cleanUrl(pageUrlStr);
		Object[] results = node.evaluateXPath("//div[@id='searchList']/dl/dd/ul[@class='detail']/li[@class='shopname']/a[@class='BL']");
		for (Object result : results) {
			String url = ((TagNode) result).getAttributeByName("href");
			ShopUrl su = new ShopUrl(url, pageUrlStr, getCityId(), 0);
			shopUrls.add(su);
		}
		return shopUrls;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected List<? extends Runnable> getNextBatchWorks() {
		Session s = SessionManager.getInstance().openSession();
		Criteria c = s.createCriteria(PageUrl.class);
		c.add(Property.forName("cityId").eq(getCityId()));
		c.add(Property.forName("totalShop").isNull());
		c.setMaxResults(ConfigurationManager.getInstance().getBatchSize());
		List<PageUrl> pageUrls = c.list();
		s.close();
		List<Workitem> works = new ArrayList<Workitem>();
		for (PageUrl pageUrl : pageUrls) {
			works.add(new Workitem(pageUrl));
		}
		return works;
	}
	
	private synchronized void saveShopUrls(List<ShopUrl> shopUrls, PageUrl pageUrl) {
		Session s = SessionManager.getInstance().openSession();
		s.beginTransaction();
		pageUrl.setTotalShop(shopUrls.size());
		s.update(pageUrl);
		for (ShopUrl shopUrl : shopUrls) {
			if (s.get(ShopUrl.class, shopUrl.getUrl()) == null) {
				s.save(shopUrl);
				printStatus(shopUrl.getUrl());
			}
		}
		s.getTransaction().commit();
		s.close();
	}
	
	class Workitem implements Runnable {
		
		private PageUrl pageUrl;

		public Workitem(PageUrl pageUrl) {
			this.pageUrl = pageUrl;
		}

		@Override
		public void run() {
			String pageUrlStr = pageUrl.getUrl();
			List<ShopUrl> shopUrls = null;
			
			try {
				shopUrls = fetchShopUrls(pageUrlStr);
			} catch (Exception e) {
				e.printStackTrace();
				return;
			}
			
			saveShopUrls(shopUrls, pageUrl);
		}
	}

}
